From 8a31888a046a56fb05f7b409537122d72e671ff7 Mon Sep 17 00:00:00 2001 From: Owen Taylor Date: Mon, 5 Nov 2001 15:56:50 +0000 Subject: [PATCH] Clamp max window width/height to 32767, not 32768 since we have to be able Mon Nov 5 10:01:49 2001 Owen Taylor * gdk/x11/gdkgeometry-x11.c (gdk_window_compute_position): Clamp max window width/height to 32767, not 32768 since we have to be able to deal with a dx/y of -32768 without getting a width of 65536 when guffaw scrolling. * gdk/x11/gdkgeometry-x11.c: Implement gdk_window_scroll() for the guffaw scrolling case, fixing some problems with copy-area case as well. Fix BadValue bug with moving windows by large amounts. * gdk/x11/gdkgeometry-x11.c (gdk_window_clip_changed): Update clip in window structue before calling gdk_window_invalidate_region since that trims new invalidations to the window's visible region. * gdk/x11/gdkwindow-x11.c (gdk_window_set_static_gravities): Really set the static window gravity on the children, not repeatedly on the window. * gtk/testgtk.c: Add a torture test for big windows and gdk_window_scroll(). --- ChangeLog | 24 +++ ChangeLog.pre-2-0 | 24 +++ ChangeLog.pre-2-10 | 24 +++ ChangeLog.pre-2-2 | 24 +++ ChangeLog.pre-2-4 | 24 +++ ChangeLog.pre-2-6 | 24 +++ ChangeLog.pre-2-8 | 24 +++ gdk/x11/gdkgeometry-x11.c | 338 ++++++++++++++++++++++++-------------- gdk/x11/gdkwindow-x11.c | 2 +- tests/testgtk.c | 220 +++++++++++++++++++++++++ 10 files changed, 604 insertions(+), 124 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0e06f79411..e8912c4145 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,27 @@ +Mon Nov 5 10:01:49 2001 Owen Taylor + + * gdk/x11/gdkgeometry-x11.c (gdk_window_compute_position): + Clamp max window width/height to 32767, not 32768 since + we have to be able to deal with a dx/y of -32768 without + getting a width of 65536 when guffaw scrolling. + + * gdk/x11/gdkgeometry-x11.c: Implement gdk_window_scroll() + for the guffaw scrolling case, fixing some problems with + copy-area case as well. Fix BadValue bug with moving windows + by large amounts. + + * gdk/x11/gdkgeometry-x11.c (gdk_window_clip_changed): Update + clip in window structue before calling gdk_window_invalidate_region + since that trims new invalidations to the window's visible + region. + + * gdk/x11/gdkwindow-x11.c (gdk_window_set_static_gravities): + Really set the static window gravity on the children, not + repeatedly on the window. + + * gtk/testgtk.c: Add a torture test for big windows and + gdk_window_scroll(). + Sun Nov 4 17:36:08 2001 Manish Singh * acconfig.h configure.in: sigsetjmp is macroized in some places, diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index 0e06f79411..e8912c4145 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,3 +1,27 @@ +Mon Nov 5 10:01:49 2001 Owen Taylor + + * gdk/x11/gdkgeometry-x11.c (gdk_window_compute_position): + Clamp max window width/height to 32767, not 32768 since + we have to be able to deal with a dx/y of -32768 without + getting a width of 65536 when guffaw scrolling. + + * gdk/x11/gdkgeometry-x11.c: Implement gdk_window_scroll() + for the guffaw scrolling case, fixing some problems with + copy-area case as well. Fix BadValue bug with moving windows + by large amounts. + + * gdk/x11/gdkgeometry-x11.c (gdk_window_clip_changed): Update + clip in window structue before calling gdk_window_invalidate_region + since that trims new invalidations to the window's visible + region. + + * gdk/x11/gdkwindow-x11.c (gdk_window_set_static_gravities): + Really set the static window gravity on the children, not + repeatedly on the window. + + * gtk/testgtk.c: Add a torture test for big windows and + gdk_window_scroll(). + Sun Nov 4 17:36:08 2001 Manish Singh * acconfig.h configure.in: sigsetjmp is macroized in some places, diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 0e06f79411..e8912c4145 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,27 @@ +Mon Nov 5 10:01:49 2001 Owen Taylor + + * gdk/x11/gdkgeometry-x11.c (gdk_window_compute_position): + Clamp max window width/height to 32767, not 32768 since + we have to be able to deal with a dx/y of -32768 without + getting a width of 65536 when guffaw scrolling. + + * gdk/x11/gdkgeometry-x11.c: Implement gdk_window_scroll() + for the guffaw scrolling case, fixing some problems with + copy-area case as well. Fix BadValue bug with moving windows + by large amounts. + + * gdk/x11/gdkgeometry-x11.c (gdk_window_clip_changed): Update + clip in window structue before calling gdk_window_invalidate_region + since that trims new invalidations to the window's visible + region. + + * gdk/x11/gdkwindow-x11.c (gdk_window_set_static_gravities): + Really set the static window gravity on the children, not + repeatedly on the window. + + * gtk/testgtk.c: Add a torture test for big windows and + gdk_window_scroll(). + Sun Nov 4 17:36:08 2001 Manish Singh * acconfig.h configure.in: sigsetjmp is macroized in some places, diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index 0e06f79411..e8912c4145 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,27 @@ +Mon Nov 5 10:01:49 2001 Owen Taylor + + * gdk/x11/gdkgeometry-x11.c (gdk_window_compute_position): + Clamp max window width/height to 32767, not 32768 since + we have to be able to deal with a dx/y of -32768 without + getting a width of 65536 when guffaw scrolling. + + * gdk/x11/gdkgeometry-x11.c: Implement gdk_window_scroll() + for the guffaw scrolling case, fixing some problems with + copy-area case as well. Fix BadValue bug with moving windows + by large amounts. + + * gdk/x11/gdkgeometry-x11.c (gdk_window_clip_changed): Update + clip in window structue before calling gdk_window_invalidate_region + since that trims new invalidations to the window's visible + region. + + * gdk/x11/gdkwindow-x11.c (gdk_window_set_static_gravities): + Really set the static window gravity on the children, not + repeatedly on the window. + + * gtk/testgtk.c: Add a torture test for big windows and + gdk_window_scroll(). + Sun Nov 4 17:36:08 2001 Manish Singh * acconfig.h configure.in: sigsetjmp is macroized in some places, diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 0e06f79411..e8912c4145 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,27 @@ +Mon Nov 5 10:01:49 2001 Owen Taylor + + * gdk/x11/gdkgeometry-x11.c (gdk_window_compute_position): + Clamp max window width/height to 32767, not 32768 since + we have to be able to deal with a dx/y of -32768 without + getting a width of 65536 when guffaw scrolling. + + * gdk/x11/gdkgeometry-x11.c: Implement gdk_window_scroll() + for the guffaw scrolling case, fixing some problems with + copy-area case as well. Fix BadValue bug with moving windows + by large amounts. + + * gdk/x11/gdkgeometry-x11.c (gdk_window_clip_changed): Update + clip in window structue before calling gdk_window_invalidate_region + since that trims new invalidations to the window's visible + region. + + * gdk/x11/gdkwindow-x11.c (gdk_window_set_static_gravities): + Really set the static window gravity on the children, not + repeatedly on the window. + + * gtk/testgtk.c: Add a torture test for big windows and + gdk_window_scroll(). + Sun Nov 4 17:36:08 2001 Manish Singh * acconfig.h configure.in: sigsetjmp is macroized in some places, diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 0e06f79411..e8912c4145 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,27 @@ +Mon Nov 5 10:01:49 2001 Owen Taylor + + * gdk/x11/gdkgeometry-x11.c (gdk_window_compute_position): + Clamp max window width/height to 32767, not 32768 since + we have to be able to deal with a dx/y of -32768 without + getting a width of 65536 when guffaw scrolling. + + * gdk/x11/gdkgeometry-x11.c: Implement gdk_window_scroll() + for the guffaw scrolling case, fixing some problems with + copy-area case as well. Fix BadValue bug with moving windows + by large amounts. + + * gdk/x11/gdkgeometry-x11.c (gdk_window_clip_changed): Update + clip in window structue before calling gdk_window_invalidate_region + since that trims new invalidations to the window's visible + region. + + * gdk/x11/gdkwindow-x11.c (gdk_window_set_static_gravities): + Really set the static window gravity on the children, not + repeatedly on the window. + + * gtk/testgtk.c: Add a torture test for big windows and + gdk_window_scroll(). + Sun Nov 4 17:36:08 2001 Manish Singh * acconfig.h configure.in: sigsetjmp is macroized in some places, diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 0e06f79411..e8912c4145 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,27 @@ +Mon Nov 5 10:01:49 2001 Owen Taylor + + * gdk/x11/gdkgeometry-x11.c (gdk_window_compute_position): + Clamp max window width/height to 32767, not 32768 since + we have to be able to deal with a dx/y of -32768 without + getting a width of 65536 when guffaw scrolling. + + * gdk/x11/gdkgeometry-x11.c: Implement gdk_window_scroll() + for the guffaw scrolling case, fixing some problems with + copy-area case as well. Fix BadValue bug with moving windows + by large amounts. + + * gdk/x11/gdkgeometry-x11.c (gdk_window_clip_changed): Update + clip in window structue before calling gdk_window_invalidate_region + since that trims new invalidations to the window's visible + region. + + * gdk/x11/gdkwindow-x11.c (gdk_window_set_static_gravities): + Really set the static window gravity on the children, not + repeatedly on the window. + + * gtk/testgtk.c: Add a torture test for big windows and + gdk_window_scroll(). + Sun Nov 4 17:36:08 2001 Manish Singh * acconfig.h configure.in: sigsetjmp is macroized in some places, diff --git a/gdk/x11/gdkgeometry-x11.c b/gdk/x11/gdkgeometry-x11.c index 64fc00f03a..b479ab5e75 100644 --- a/gdk/x11/gdkgeometry-x11.c +++ b/gdk/x11/gdkgeometry-x11.c @@ -110,6 +110,169 @@ _gdk_window_init_position (GdkWindow *window) gdk_window_compute_position (impl, &parent_pos, &impl->position_info); } +static void +gdk_window_copy_area_scroll (GdkWindow *window, + GdkRectangle *dest_rect, + gint dx, + gint dy) +{ + GdkWindowObject *obj = GDK_WINDOW_OBJECT (window); + GList *tmp_list; + + if (dest_rect->width > 0 && dest_rect->height > 0) + { + GC gc; + XGCValues values; + + values.graphics_exposures = True; + gc = XCreateGC (GDK_WINDOW_XDISPLAY (window), + GDK_WINDOW_XID (window), + GCGraphicsExposures, &values); + + gdk_window_queue_translation (window, dx, dy); + + XCopyArea (GDK_WINDOW_XDISPLAY (window), + GDK_WINDOW_XID (window), + GDK_WINDOW_XID (window), + gc, + dest_rect->x - dx, dest_rect->y - dy, + dest_rect->width, dest_rect->height, + dest_rect->x, dest_rect->y); + + XFreeGC (GDK_WINDOW_XDISPLAY (window), gc); + } + + tmp_list = obj->children; + while (tmp_list) + { + GdkWindow *child = GDK_WINDOW (tmp_list->data); + GdkWindowObject *child_obj = GDK_WINDOW_OBJECT (child); + + gdk_window_move (child, child_obj->x + dx, child_obj->y + dy); + + tmp_list = tmp_list->next; + } +} + +static void +compute_intermediate_position (GdkXPositionInfo *position_info, + GdkXPositionInfo *new_info, + gint d_xoffset, + gint d_yoffset, + GdkRectangle *new_position) +{ + gint new_x0, new_x1, new_y0, new_y1; + + /* Wrap d_xoffset, d_yoffset into [-32768,32767] range. For the + * purposes of subwindow movement, it doesn't matter if we are + * off by a factor of 65536, and if we don't do this range + * reduction, we'll end up with invalid widths. + */ + d_xoffset = (gint16)d_xoffset; + d_yoffset = (gint16)d_yoffset; + + if (d_xoffset < 0) + { + new_x0 = position_info->x + d_xoffset; + new_x1 = position_info->x + position_info->width; + } + else + { + new_x0 = position_info->x; + new_x1 = position_info->x + new_info->width + d_xoffset; + } + + new_position->x = new_x0; + new_position->width = new_x1 - new_x0; + + if (d_yoffset < 0) + { + new_y0 = position_info->y + d_yoffset; + new_y1 = position_info->y + position_info->height; + } + else + { + new_y0 = position_info->y; + new_y1 = position_info->y + new_info->height + d_yoffset; + } + + new_position->y = new_y0; + new_position->height = new_y1 - new_y0; +} + +static void +gdk_window_guffaw_scroll (GdkWindow *window, + gint dx, + gint dy) +{ + GdkWindowObject *obj = GDK_WINDOW_OBJECT (window); + GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (obj->impl); + + gint d_xoffset = -dx; + gint d_yoffset = -dy; + GdkRectangle new_position; + GdkXPositionInfo new_info; + GdkWindowParentPos parent_pos; + GList *tmp_list; + + gdk_window_compute_parent_pos (impl, &parent_pos); + gdk_window_compute_position (impl, &parent_pos, &new_info); + + parent_pos.x += obj->x; + parent_pos.y += obj->y; + parent_pos.x11_x += new_info.x; + parent_pos.x11_y += new_info.y; + parent_pos.clip_rect = new_info.clip_rect; + + gdk_window_tmp_unset_bg (window); + + if (d_xoffset < 0 || d_yoffset < 0) + gdk_window_queue_translation (window, MIN (d_xoffset, 0), MIN (d_yoffset, 0)); + + gdk_window_set_static_gravities (window, TRUE); + + compute_intermediate_position (&impl->position_info, &new_info, d_xoffset, d_yoffset, + &new_position); + + XMoveResizeWindow (GDK_WINDOW_XDISPLAY (window), + GDK_WINDOW_XID (window), + new_position.x, new_position.y, new_position.width, new_position.height); + + tmp_list = obj->children; + while (tmp_list) + { + GDK_WINDOW_OBJECT(tmp_list->data)->x -= d_xoffset; + GDK_WINDOW_OBJECT(tmp_list->data)->y -= d_yoffset; + + gdk_window_premove (tmp_list->data, &parent_pos); + tmp_list = tmp_list->next; + } + + XMoveWindow (GDK_WINDOW_XDISPLAY (window), + GDK_WINDOW_XID (window), + new_position.x - d_xoffset, new_position.y - d_yoffset); + + if (d_xoffset > 0 || d_yoffset > 0) + gdk_window_queue_translation (window, MAX (d_xoffset, 0), MAX (d_yoffset, 0)); + + XMoveResizeWindow (GDK_WINDOW_XDISPLAY (window), + GDK_WINDOW_XID (window), + impl->position_info.x, impl->position_info.y, + impl->position_info.width, impl->position_info.height); + + if (impl->position_info.no_bg) + gdk_window_tmp_reset_bg (window); + + impl->position_info = new_info; + + tmp_list = obj->children; + while (tmp_list) + { + gdk_window_postmove (tmp_list->data, &parent_pos); + tmp_list = tmp_list->next; + } +} + /** * gdk_window_scroll: * @window: a #GdkWindow @@ -131,97 +294,60 @@ gdk_window_scroll (GdkWindow *window, gint dy) { gboolean can_guffaw_scroll = FALSE; + GdkRegion *invalidate_region; GdkWindowImplX11 *impl; GdkWindowObject *obj; + GdkRectangle dest_rect; g_return_if_fail (GDK_IS_WINDOW (window)); - obj = GDK_WINDOW_OBJECT (window); + if (GDK_WINDOW_DESTROYED (window)) + return; + obj = GDK_WINDOW_OBJECT (window); impl = GDK_WINDOW_IMPL_X11 (obj->impl); - - if (GDK_WINDOW_DESTROYED (window)) + + if (dx == 0 && dy == 0) return; /* Move the current invalid region */ if (obj->update_area) gdk_region_offset (obj->update_area, dx, dy); + invalidate_region = gdk_region_rectangle (&impl->position_info.clip_rect); + + dest_rect = impl->position_info.clip_rect; + dest_rect.x += dx; + dest_rect.y += dy; + gdk_rectangle_intersect (&dest_rect, &impl->position_info.clip_rect, &dest_rect); + + if (dest_rect.width > 0 && dest_rect.height > 0) + { + GdkRegion *tmp_region; + + tmp_region = gdk_region_rectangle (&dest_rect); + gdk_region_subtract (invalidate_region, tmp_region); + gdk_region_destroy (tmp_region); + } + + gdk_window_invalidate_region (window, invalidate_region, TRUE); + gdk_region_destroy (invalidate_region); + /* We can guffaw scroll if we are a child window, and the parent - * does not extend beyond our edges. + * does not extend beyond our edges. Otherwise, we use XCopyArea, then + * move any children later */ - if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD) { GdkWindowImplX11 *parent_impl = GDK_WINDOW_IMPL_X11 (obj->parent->impl); - can_guffaw_scroll = (obj->x <= 0 && - obj->y <= 0 && - obj->x + impl->width >= parent_impl->width && - obj->y + impl->height >= parent_impl->height); + can_guffaw_scroll = ((dx == 0 || (obj->x <= 0 && obj->x + impl->width >= parent_impl->width)) && + (dy == 0 || (obj->y <= 0 && obj->y + impl->height >= parent_impl->height))); } if (!obj->children || !can_guffaw_scroll) - { - /* Use XCopyArea, then move any children later - */ - GList *tmp_list; - GdkRegion *invalidate_region; - GdkRectangle dest_rect; - - invalidate_region = gdk_region_rectangle (&impl->position_info.clip_rect); - - dest_rect = impl->position_info.clip_rect; - dest_rect.x += dx; - dest_rect.y += dy; - gdk_rectangle_intersect (&dest_rect, &impl->position_info.clip_rect, &dest_rect); - - if (dest_rect.width > 0 && dest_rect.height > 0) - { - GC gc; - XGCValues values; - GdkRegion *tmp_region; - - tmp_region = gdk_region_rectangle (&dest_rect); - gdk_region_subtract (invalidate_region, tmp_region); - gdk_region_destroy (tmp_region); - - gdk_window_queue_translation (window, dx, dy); - - values.graphics_exposures = True; - gc = XCreateGC (GDK_WINDOW_XDISPLAY (window), - GDK_WINDOW_XID (window), - GCGraphicsExposures, &values); - - XCopyArea (GDK_WINDOW_XDISPLAY (window), - GDK_WINDOW_XID (window), - GDK_WINDOW_XID (window), - gc, - dest_rect.x - dx, dest_rect.y - dy, - dest_rect.width, dest_rect.height, - dest_rect.x, dest_rect.y); - - XFreeGC (GDK_WINDOW_XDISPLAY (window), gc); - } - - gdk_window_invalidate_region (window, invalidate_region, TRUE); - gdk_region_destroy (invalidate_region); - - tmp_list = obj->children; - while (tmp_list) - { - GdkWindow * child = GDK_WINDOW (tmp_list->data); - - gdk_window_move (child, obj->x + dx, obj->y + dy); - - tmp_list = tmp_list->next; - } - } + gdk_window_copy_area_scroll (window, &dest_rect, dx, dy); else - { - /* Guffaw scroll - */ - g_warning ("gdk_window_scroll(): guffaw scrolling not yet implemented"); - } + gdk_window_guffaw_scroll (window, dx, dy); } void @@ -278,38 +404,19 @@ _gdk_window_move_resize_child (GdkWindow *window, if (d_xoffset != 0 || d_yoffset != 0) { - gint new_x0, new_y0, new_x1, new_y1; + GdkRectangle new_position; gdk_window_set_static_gravities (window, TRUE); if (d_xoffset < 0 || d_yoffset < 0) gdk_window_queue_translation (window, MIN (d_xoffset, 0), MIN (d_yoffset, 0)); - - if (d_xoffset < 0) - { - new_x0 = impl->position_info.x + d_xoffset; - new_x1 = impl->position_info.x + impl->position_info.width; - } - else - { - new_x0 = impl->position_info.x; - new_x1 = impl->position_info.x + new_info.width + d_xoffset; - } - if (d_yoffset < 0) - { - new_y0 = impl->position_info.y + d_yoffset; - new_y1 = impl->position_info.y + impl->position_info.height; - } - else - { - new_y0 = impl->position_info.y; - new_y1 = impl->position_info.y + new_info.height + d_yoffset; - } + compute_intermediate_position (&impl->position_info, &new_info, d_xoffset, d_yoffset, + &new_position); XMoveResizeWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window), - new_x0, new_y0, new_x1 - new_x0, new_y1 - new_y0); + new_position.x, new_position.y, new_position.width, new_position.height); tmp_list = obj->children; while (tmp_list) @@ -320,7 +427,7 @@ _gdk_window_move_resize_child (GdkWindow *window, XMoveWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window), - new_x0 + dx, new_y0 + dy); + new_position.x + dx, new_position.y + dy); if (d_xoffset > 0 || d_yoffset > 0) gdk_window_queue_translation (window, MAX (d_xoffset, 0), MAX (d_yoffset, 0)); @@ -400,7 +507,7 @@ gdk_window_compute_position (GdkWindowImplX11 *window, info->big = FALSE; - if (window->width <= 32768) + if (window->width <= 32767) { info->width = window->width; info->x = parent_pos->x + wrapper->x - parent_pos->x11_x; @@ -408,11 +515,11 @@ gdk_window_compute_position (GdkWindowImplX11 *window, else { info->big = TRUE; - info->width = 32768; + info->width = 32767; if (parent_pos->x + wrapper->x < -16384) { if (parent_pos->x + wrapper->x + window->width < 16384) - info->x = parent_pos->x + wrapper->x + window->width - 32768 - parent_pos->x11_x; + info->x = parent_pos->x + wrapper->x + window->width - info->width - parent_pos->x11_x; else info->x = -16384 - parent_pos->x11_y; } @@ -420,7 +527,7 @@ gdk_window_compute_position (GdkWindowImplX11 *window, info->x = parent_pos->x + wrapper->x - parent_pos->x11_x; } - if (window->height <= 32768) + if (window->height <= 32767) { info->height = window->height; info->y = parent_pos->y + wrapper->y - parent_pos->x11_y; @@ -428,11 +535,11 @@ gdk_window_compute_position (GdkWindowImplX11 *window, else { info->big = TRUE; - info->height = 32768; + info->height = 32767; if (parent_pos->y + wrapper->y < -16384) { if (parent_pos->y + wrapper->y + window->height < 16384) - info->y = parent_pos->y + wrapper->y + window->height - 32768 - parent_pos->x11_y; + info->y = parent_pos->y + wrapper->y + window->height - info->height - parent_pos->x11_y; else info->y = -16384 - parent_pos->x11_y; } @@ -576,36 +683,17 @@ gdk_window_premove (GdkWindow *window, if (d_xoffset != 0 || d_yoffset != 0) { - gint new_x0, new_y0, new_x1, new_y1; + GdkRectangle new_position; if (d_xoffset < 0 || d_yoffset < 0) gdk_window_queue_translation (window, MIN (d_xoffset, 0), MIN (d_yoffset, 0)); - - if (d_xoffset < 0) - { - new_x0 = impl->position_info.x + d_xoffset; - new_x1 = impl->position_info.x + impl->position_info.width; - } - else - { - new_x0 = impl->position_info.x; - new_x1 = impl->position_info.x + new_info.width + d_xoffset; - } - if (d_yoffset < 0) - { - new_y0 = impl->position_info.y + d_yoffset; - new_y1 = impl->position_info.y + impl->position_info.height; - } - else - { - new_y0 = impl->position_info.y; - new_y1 = impl->position_info.y + new_info.height + d_yoffset; - } + compute_intermediate_position (&impl->position_info, &new_info, d_xoffset, d_yoffset, + &new_position); XMoveResizeWindow (GDK_DRAWABLE_XDISPLAY (window), GDK_DRAWABLE_XID (window), - new_x0, new_y0, new_x1 - new_x0, new_y1 - new_y0); + new_position.x, new_position.y, new_position.width, new_position.height); } tmp_list = obj->children; @@ -818,6 +906,11 @@ gdk_window_clip_changed (GdkWindow *window, GdkRectangle *old_clip, GdkRectangle old_clip_region = gdk_region_rectangle (old_clip); new_clip_region = gdk_region_rectangle (new_clip); + /* We need to update this here because gdk_window_invalidate_region makes + * use if it (through gdk_drawable_get_visible_region + */ + impl->position_info.clip_rect = *new_clip; + /* Trim invalid region of window to new clip rectangle */ if (obj->update_area) @@ -835,4 +928,3 @@ gdk_window_clip_changed (GdkWindow *window, GdkRectangle *old_clip, GdkRectangle gdk_region_destroy (new_clip_region); gdk_region_destroy (old_clip_region); } - diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c index a4563ba171..f6d6d89d90 100644 --- a/gdk/x11/gdkwindow-x11.c +++ b/gdk/x11/gdkwindow-x11.c @@ -3931,7 +3931,7 @@ gdk_window_set_static_gravities (GdkWindow *window, tmp_list = private->children; while (tmp_list) { - gdk_window_set_static_win_gravity (window, use_static); + gdk_window_set_static_win_gravity (tmp_list->data, use_static); tmp_list = tmp_list->next; } diff --git a/tests/testgtk.c b/tests/testgtk.c index b5f42ebe08..5cbdad12df 100644 --- a/tests/testgtk.c +++ b/tests/testgtk.c @@ -143,6 +143,225 @@ destroy_tooltips (GtkWidget *widget, GtkWindow **window) *window = NULL; } + +/* + * Big windows and guffaw scrolling + */ + +static gboolean +pattern_expose (GtkWidget *widget, + GdkEventExpose *event, + gpointer data) +{ + GdkColor *color; + GdkWindow *window = event->window; + + color = g_object_get_data (G_OBJECT (window), "pattern-color"); + if (color) + { + GdkGC *tmp_gc = gdk_gc_new (window); + gdk_gc_set_rgb_fg_color (tmp_gc, color); + + gdk_draw_rectangle (window, tmp_gc, TRUE, + event->area.x, event->area.y, + event->area.width, event->area.height); + + g_object_unref (G_OBJECT (tmp_gc)); + } + + return FALSE; +} + +static void +pattern_set_bg (GtkWidget *widget, + GdkWindow *child, + gint level) +{ + static const GdkColor colors[] = { + { 0, 0x4444, 0x4444, 0xffff }, + { 0, 0x8888, 0x8888, 0xffff }, + { 0, 0xaaaa, 0xaaaa, 0xffff } + }; + + g_object_set_data (G_OBJECT (child), "pattern-color", (gpointer)&colors[level]); + gdk_window_set_user_data (child, widget); +} + +static void +create_pattern (GtkWidget *widget, + GdkWindow *parent, + gint level, + gint width, + gint height) +{ + gint h = 1; + gint i = 0; + + GdkWindow *child; + + while (2 * h <= height) + { + gint w = 1; + gint j = 0; + + while (2 * w <= width) + { + if ((i + j) % 2 == 0) + { + gint x = w - 1; + gint y = h - 1; + + GdkWindowAttr attributes; + + attributes.window_type = GDK_WINDOW_CHILD; + attributes.x = x; + attributes.y = y; + attributes.width = w; + attributes.height = h; + attributes.wclass = GDK_INPUT_OUTPUT; + attributes.event_mask = GDK_EXPOSURE_MASK; + attributes.visual = gtk_widget_get_visual (widget); + attributes.colormap = gtk_widget_get_colormap (widget); + + child = gdk_window_new (parent, &attributes, + GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP); + + pattern_set_bg (widget, child, level); + + if (level < 2) + create_pattern (widget, child, level + 1, w, h); + + gdk_window_show (child); + } + j++; + w *= 2; + } + i++; + h *= 2; + } +} + +#define PATTERN_SIZE (1 << 18) + +static void +pattern_hadj_changed (GtkAdjustment *adj, + GtkWidget *darea) +{ + gint *old_value = g_object_get_data (G_OBJECT (adj), "old-value"); + gint new_value = adj->value; + + if (GTK_WIDGET_REALIZED (darea)) + { + gdk_window_scroll (darea->window, *old_value - new_value, 0); + *old_value = new_value; + } +} + +static void +pattern_vadj_changed (GtkAdjustment *adj, + GtkWidget *darea) +{ + gint *old_value = g_object_get_data (G_OBJECT (adj), "old-value"); + gint new_value = adj->value; + + if (GTK_WIDGET_REALIZED (darea)) + { + gdk_window_scroll (darea->window, 0, *old_value - new_value); + *old_value = new_value; + } +} + +static void +pattern_realize (GtkWidget *widget, + gpointer data) +{ + pattern_set_bg (widget, widget->window, 0); + create_pattern (widget, widget->window, 1, PATTERN_SIZE, PATTERN_SIZE); +} + +static void +create_big_windows (void) +{ + static GtkWidget *window = NULL; + GtkWidget *darea, *table, *scrollbar; + GtkWidget *eventbox; + GtkAdjustment *hadj; + GtkAdjustment *vadj; + static gint current_x; + static gint current_y; + + if (!window) + { + current_x = 0; + current_y = 0; + + window = gtk_dialog_new_with_buttons ("Big Windows", + NULL, 0, + GTK_STOCK_CLOSE, + GTK_RESPONSE_NONE, + NULL); + + gtk_window_set_default_size (GTK_WINDOW (window), 200, 300); + + gtk_signal_connect (GTK_OBJECT (window), "destroy", + GTK_SIGNAL_FUNC (gtk_widget_destroyed), + &window); + + gtk_signal_connect (GTK_OBJECT (window), "response", + GTK_SIGNAL_FUNC (gtk_widget_destroy), + NULL); + + table = gtk_table_new (2, 2, FALSE); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), + table, TRUE, TRUE, 0); + + darea = gtk_drawing_area_new (); + + hadj = (GtkAdjustment *)gtk_adjustment_new (0, 0, PATTERN_SIZE, 10, 100, 100); + gtk_signal_connect (GTK_OBJECT (hadj), "value_changed", + GTK_SIGNAL_FUNC (pattern_hadj_changed), darea); + g_object_set_data (G_OBJECT (hadj), "old-value", ¤t_x); + + vadj = (GtkAdjustment *)gtk_adjustment_new (0, 0, PATTERN_SIZE, 10, 100, 100); + gtk_signal_connect (GTK_OBJECT (vadj), "value_changed", + GTK_SIGNAL_FUNC (pattern_vadj_changed), darea); + g_object_set_data (G_OBJECT (vadj), "old-value", ¤t_y); + + gtk_signal_connect (GTK_OBJECT (darea), "realize", + GTK_SIGNAL_FUNC (pattern_realize), + NULL); + gtk_signal_connect (GTK_OBJECT (darea), "expose_event", + GTK_SIGNAL_FUNC (pattern_expose), + NULL); + + eventbox = gtk_event_box_new (); + gtk_table_attach (GTK_TABLE (table), eventbox, + 0, 1, 0, 1, + GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, + 0, 0); + + gtk_container_add (GTK_CONTAINER (eventbox), darea); + + scrollbar = gtk_hscrollbar_new (hadj); + gtk_table_attach (GTK_TABLE (table), scrollbar, + 0, 1, 1, 2, + GTK_FILL | GTK_EXPAND, GTK_FILL, + 0, 0); + + scrollbar = gtk_vscrollbar_new (vadj); + gtk_table_attach (GTK_TABLE (table), scrollbar, + 1, 2, 0, 1, + GTK_FILL, GTK_EXPAND | GTK_FILL, + 0, 0); + + } + + if (!GTK_WIDGET_VISIBLE (window)) + gtk_widget_show_all (window); + else + gtk_widget_hide (window); +} + /* * GtkButton */ @@ -10644,6 +10863,7 @@ struct { gboolean do_not_benchmark; } buttons[] = { + { "big windows", create_big_windows }, { "button box", create_button_box }, { "buttons", create_buttons }, { "check buttons", create_check_buttons }, -- 2.30.2